package cn.itsource.org.service.impl;

import cn.itsource.base.service.impl.BaseServiceImpl;
import cn.itsource.global.exception.BusinessException;
import cn.itsource.org.query.DepartmentQuery;
import cn.itsource.base.util.PageList;
import cn.itsource.org.domain.Department;
import cn.itsource.org.mapper.DepartmentMapper;
import cn.itsource.org.service.IDepartmentService;
import cn.itsource.base.util.ErrorCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DepartmentServiceImpl extends BaseServiceImpl<Department> implements IDepartmentService {
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    private static String TREE_NAME = "deptTree";
    @Override
    @Transactional
    @CacheEvict(cacheNames="books")//删除
    public void save(Department department) {
        //先保存
        departmentMapper.save(department);//这里面是不是一定有id
        updateDirPath(department);
    }

    private void updateDirPath(Department department) {

        //的到上级部门id
        Long parentId = department.getParentId();
        //查询上级部门
        Department department1 = departmentMapper.selectById(parentId);
        //获取上级部门的path
        String dirPath = department1.getDirPath();
        //构建自己的path
        dirPath = dirPath +"/"+ department.getId();
        //设置path
        department.setDirPath(dirPath);
        departmentMapper.update(department);
    }

    @CacheEvict(cacheNames="books")
    @Override
    public void update(Department department) {
        //如果你不是最后一级部门 就不准修改上级部门
        Long id = department.getId();

//        int i = 1/0;

        Department department1 = departmentMapper.selectById(id);
        if(department1 == null||department1.getParentId() == null){
            throw new BusinessException(ErrorCode.BUSINESS_DEPT_ERROR.getCode());//业务异常
        }
        if(!department1.getParentId().equals(department.getParentId())){
            //这里有个小问题mybatis
            List<Department> departments = departmentMapper.selectByPid(id);
            if(departments.size() > 0){
                throw new BusinessException(ErrorCode.BUSINESS_DEPT2_ERROR.getCode());//业务异常
            }
        }
        updateDirPath(department);
//        我在删除 1 2 3
    }

    @Override
    @CacheEvict(cacheNames = "books")
    public void deleteById(Long id) {
        departmentMapper.deleteById(id);
    }

    @Override
    @CacheEvict(cacheNames = "books")
    public void batchDeleteByIds(List<Long> ids) {
        departmentMapper.batchDeleteByIds(ids);
    }


    @Override
    public PageList<Department> queryPage(DepartmentQuery query) {
        if(query.getCurrentPage() < 1){
            throw new RuntimeException("");
        }
        //分页查询
        List<Department> departments = departmentMapper.query(query);
        //创建分页接收对象
        PageList<Department> pageList = new PageList();
        //设置分页数据
        pageList.setData(departments);
        //设置分页总条数
        pageList.setCount(departmentMapper.queryCount(query));
        return pageList;
    }

    /**
     * 10000条    1000 + 10000*10000 = ?????
     * @return
     */
//    @Override
//    public List<Department> getDepartmentTree() {
//        //10W用户同时在查询
//        //首先去redis里面去查询
//        List<Department> o = (List<Department>)redisTemplate.opsForValue().get(TREE_NAME);
//        //lock 排他锁（只有一个人可以用）
//        //又去查询一次redis
//        if(o == null){//如果没有 查询数据
//            List<Department> departments2 = getDepartments2();//查询数据库
//            redisTemplate.opsForValue().set(TREE_NAME,departments2);//保存一份到reids里面
//            return departments2;//返回Tree
//        }
//        //unlock
//        return o;
//    }

    //SpringCache写法
    @Cacheable(cacheNames="books",key="'deptName'")
    public List<Department> getDepartmentTree() {
        List<Department> departments2 = getDepartments2();
        return departments2;
    }



    private List<Department> getDepartments3(){
        //第一个步找顶层
        List<Department> departments = departmentMapper.selectAll();//从数据库里面查询全部
        List<Department> top = new ArrayList<>();
        Map<Long, Department> map = departments.stream()
                .collect(Collectors.toMap(Department::getId, item -> item, (Key1, key2) -> Key1));
        //collect 收集
        //Collectors java8提供的一些收集器
        //(Key1, key2) -> Key1)  map key 不允许重复

        departments.stream().filter(dept->{
            if(dept.getParentId() == null){
                top.add(dept);
                return false;
            }
            return true;
        }).forEach(detp->{
            //只要你不是顶层  你一定是某个人的儿子
            Long parentId = detp.getParentId();//爹的id
            Department department1 = map.get(parentId);
            department1.getChildren().add(detp);//找到爹 把自己放进去
        });
        return top;
    }

    private List<Department> getDepartments2(){
        //第一个步找顶层
        List<Department> departments = departmentMapper.selectAll();//从数据库里面查询全部
        List<Department> top = new ArrayList<>();
        //将 list 转 map
        Map<Long,Department> map = new HashMap<>();
        for (Department department : departments) {
            map.put(department.getId(),department);
        }
        //怎么找顶层 怎么找儿子
        for (Department department : departments) {
            if(department.getParentId() == null){
                top.add(department);
            }else {
                //只要你不是顶层  你一定是某个人的儿子
                Long parentId = department.getParentId();//爹的id
                Department department1 = map.get(parentId);
                department1.getChildren().add(department);//找到爹 把自己放进去
            }
        }
        return top;
    }

    /**
     * 垃圾
     * @return
     */
    private List<Department> getDepartments() {
        //第一个步找顶层
        List<Department> departments = departmentMapper.selectAll();//从数据库里面查询全部
        List<Department> top = new ArrayList<>();
        for (Department department : departments) {
            if(department.getParentId() == null){
                top.add(department);
            }
        }
        for (Department department : departments) {
            for (Department department1 : departments) {
                //找到儿子了
                if(department.getId().equals(department1.getParentId())){
                    department.getChildren().add(department1);
                }
            }
        }
        //为什么要返回top
        return top;
    }
}
